package com.sen.gulimall.cart.config;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Kisen
 * @email liuqs@jaid.cn
 * @date 2022/8/25 19:33
 * @detail 线程池配置类
 */
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig implements AsyncConfigurer {

    @Value("${thread.pool.core-pool-size:20}")
    private int corePoolSize; //核心线程数

    @Value("${thread.pool.max-pool-size:200}")
    private int maxPoolSize; //最大线程数

    @Value("${thread.pool.queue-capacity:100}")
    private int queueCapacity; //队列最大长度

    @Value("${thread.pool.keep-alive-seconds:30}")
    private int keepAliveSeconds; //线程池维护线程所允许的空闲时间

    @Value("${thread.pool.thread-name-prefix:Async-Service-}")
    private String threadNamePrefix; //线程池中的线程名称前缀

    /**
     * 默认异步线程池
     *
     * @return
     */
    @Override
    @Bean("taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        executor.setCorePoolSize(corePoolSize);
        //设置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //设置队列最大长度
        executor.setQueueCapacity(queueCapacity);
        //设置线程池维护线程所允许的空闲时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        //设置线程池中的线程名称前缀
        executor.setThreadNamePrefix(threadNamePrefix);
        //设置线程池对拒绝任务(无线程可用)的处理策略 ThreadPoolExecutor.CallerRunsPolicy策略，调用者的线程会执行该任务，如果执行器已关闭，则丢弃.
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //初始化
        executor.initialize();
        return executor;
    }

    /**
     * 异步任务中异常处理
     *
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}
